package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.Movement;
import com.itheima.domain.vo.*;
import com.itheima.service.db.Logger;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.db.UserService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.MovementService;
import com.itheima.service.mongo.VisitorService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.DateFormatUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import redis.clients.jedis.Jedis;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class MovementManager {
    @Reference
    private UserService userService;
    @Reference
    private MovementService movementService;
    @Autowired
    private OssTemplate ossTemplate;
    @Reference
    private UserInfoService userInfoService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private MovementMQManager movementMQManager;

    /**
     * 发布动态
     *
     * @param movement     动态信息对象
     * @param imageContent 动态图片对象
     */
    @Logger(type = "0201")
    public void addMovement(Movement movement, MultipartFile[] imageContent) throws IOException {

        Jedis jedis = new Jedis("192.168.136.160", 6379);
        jedis.select(1);
        Long id = UserHolder.getId ();
        String phone = userService.userIdByPhone (id);
        String value = jedis.get (ConstantUtil.FREEZE_USERMovement + phone);
        if (value != null) {
            throw new RuntimeException ("该用户发布动态已被封禁");
        }

        //生成一个ObjectId
        ObjectId objectId = ObjectId.get();
        movement.setId(objectId);
        //1.将图片上传到oss阿里云平台
        //定义一个集合,存储图片路径
        List<String> imgPaths = new ArrayList<>();
        if (imageContent != null && imageContent.length != 0) {
            //遍历图片对象
            for (MultipartFile file : imageContent) {
                //上传图片,获取图片路径
                String path = ossTemplate.upload(file.getOriginalFilename(), file.getInputStream());
                imgPaths.add(path);
            }
        }
        //2.获取当前登录对象id
        Long loginUserId = UserHolder.getId();
        //3.构建movement对象(填充部分参数)
        //设置当前用户id
        movement.setUserId(loginUserId);
        //TODO 大数据推荐id 暂时写死
        //movement.setPid(1L);
        //设置图片信息
        movement.setMedias(imgPaths);
        //TODO 后续华为云进行数据审核 暂时写死
        movement.setState(0);
        //公开都能看见 默认数据 本项目没有使用
        movement.setSeeType(1);
        movementService.save(movement);

        System.out.println("------------->>>>>>>>>>>" + movement.getId());
        //发送mq消息,告诉后台进行动态审核
        rocketMQTemplate.convertAndSend("tanhua-movement-161", movement.getId().toHexString());
        //调用方法,发送mq消息,进行动态的后期推荐操作
        movementMQManager.sendMsg(movement.getId().toHexString(), MovementMQManager.MOVEMENT_PUBLISH);
    }

    /**
     * 查询用户的动态集合
     *
     * @param pageNum  页码
     * @param pagesize 每页显示的数据
     * @param userId   用户id
     * @return 用户的动态数据集合
     */
    public PageBeanVo findAllMovements(Integer pageNum, Integer pagesize, Long userId) {
        //1.分页查询我的动态
        PageBeanVo pageBeanVo = movementService.findAllMovements(pageNum, pagesize, userId);
        //2.进行数据转移
        //2.1创建页面所需要的数据对象
        List<MovementVo> movementVoList = new ArrayList<>();
        //2.2数据库返回的数据
        List<Movement> movementsItems = (List<Movement>) pageBeanVo.getItems();
        System.out.println("我的动态:" + movementsItems);
        if (CollectionUtil.isNotEmpty(movementsItems)) {
            for (Movement movement : movementsItems) {
                MovementVo movementVo = new MovementVo();
                //查询用户个人信息
                UserInfo userInfo = userInfoService.findById(movement.getUserId());
                //数据迁移
                BeanUtil.copyProperties(userInfo, movementVo);
                BeanUtil.copyProperties(movement, movementVo);
                if (StrUtil.isNotEmpty(userInfo.getTags())) {
                    movementVo.setTags(userInfo.getTags().split(","));//赋值标签
                }
                if (CollectionUtil.isNotEmpty(movement.getMedias())) {
                    movementVo.setImageContent(movement.getMedias().toArray(new String[]{}));//设置图片
                }
                movementVo.setDistance("3.2公里"); //TODO 暂时写死
                movementVo.setCreateDate(DateFormatUtil.format(new Date(movement.getCreated())));
                //是否点赞和是否喜欢 下一天的代码(暂时写死)
                String likeKey = StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movement.getId());
                if (stringRedisTemplate.hasKey(likeKey)) {
                    movementVo.setHasLiked(1);
                }
                String loveKey = StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, movement.getId());
                if (stringRedisTemplate.hasKey(loveKey)) {
                    movementVo.setHasLoved(1);
                }
                //将vo放入集合
                movementVoList.add(movementVo);
            }
        }
        //System.out.println("个人动态"+movementsItems);
        //System.out.println("个人动态vo"+movementVoList);
        pageBeanVo.setItems(movementVoList);
        System.out.println("动态:" + pageBeanVo.getItems());
        return pageBeanVo;
    }

    /**
     * 查看好友动态
     *
     * @param pageNum  页码
     * @param pageSize 每页条数
     * @return 返回好友动态数据
     */
    public PageBeanVo friendMovement(Integer pageNum, Integer pageSize) {
        //获取当前登录用户id
        Long loginUserId = UserHolder.getId();
        //查询好友发布的动态
        PageBeanVo pageBeanVo = movementService.friendMovement(pageNum, pageSize, loginUserId);
        //数据转移
        //重新构建返回对象
        List<MovementVo> movementVoList = new ArrayList<>();
        //数据库返回对象集合
        List<Movement> items = (List<Movement>) pageBeanVo.getItems();
        System.out.println(items);
        //如果集合不为空
        if (CollectionUtil.isNotEmpty(items)) {
            for (Movement movement : items) {
                //构建返回值
                MovementVo movementVo = new MovementVo();
                //查询用户信息
                UserInfo userInfo = userInfoService.findById(movement.getUserId());
                //数据转移
                BeanUtil.copyProperties(userInfo, movementVo);
                BeanUtil.copyProperties(movement, movementVo);
                if (StrUtil.isNotEmpty(userInfo.getTags())) {
                    String[] tags = userInfo.getTags().split(",");
                    movementVo.setTags(tags);
                }
                if (CollectionUtil.isNotEmpty(movement.getMedias())) {
                    movementVo.setImageContent(movement.getMedias().toArray(new String[]{}));
                }
                movementVo.setDistance("3.2公里"); //TODO 暂时写死
                movementVo.setCreateDate(DateFormatUtil.format(new Date(movement.getCreated())));
                //查询redis中是否有标志
                String likeKey = StrUtil.format(ConstantUtil.MOVEMENT_LIKE, loginUserId, movement.getId().toHexString());
                if (stringRedisTemplate.hasKey(likeKey)) {
                    movementVo.setHasLiked(1);
                }
                String loveKey = StrUtil.format(ConstantUtil.MOVEMENT_LOVE, loginUserId, movement.getId().toHexString());
                if (stringRedisTemplate.hasKey(loveKey)) {
                    movementVo.setHasLoved(1);
                }
                movementVoList.add(movementVo);
            }
        }
        //4.封装pageBeanVo
        pageBeanVo.setItems(movementVoList);
        //返回对象
        return pageBeanVo;
    }

    /**
     * 查看推荐动态列表
     *
     * @param pageNum  页码
     * @param pageSize 每页显示条数
     * @return 推荐动态对象
     */
    public PageBeanVo recommendMovement(Integer pageNum, Integer pageSize) {
        Long userId = UserHolder.getId();
        //查询推荐动态数据
        PageBeanVo pageBeanVo = movementService.recommendMovement(pageNum, pageSize, userId);
        //构建返回数据对象
        List<MovementVo> movementVoList = new ArrayList<>();
        List<Movement> items = (List<Movement>) pageBeanVo.getItems();
        System.out.println(items);
        if (CollectionUtil.isNotEmpty(items)) {
            for (Movement movement : items) {
                //构建对象
                MovementVo movementVo = new MovementVo();
                //查询用户个人信息
                UserInfo userInfo = userInfoService.findById(movement.getUserId());
                //数据转移
                movementVo.setUserInfo(userInfo);
                movementVo.setMovement(movement);
                //查询redis中是否有标志
                String likeKey = StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movement.getId().toHexString());
                if (stringRedisTemplate.hasKey(likeKey)) {
                    movementVo.setHasLiked(1);
                }
                String loveKey = StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, movement.getId().toHexString());
                if (stringRedisTemplate.hasKey(loveKey)) {
                    movementVo.setHasLoved(1);
                }
                movementVoList.add(movementVo);
            }
        }
        System.out.println(movementVoList);
        pageBeanVo.setItems(movementVoList);
        return pageBeanVo;
    }

    @Reference
    private CommentService commentService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 点赞动态
     *
     * @param movementId 动态id
     * @return 点赞数
     */
    @Logger(type = "0203")
    public Integer likeMovement(String movementId) {
        //获取登录用户
        Long userId = UserHolder.getId();
        //构建评论对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        //设置对动态点赞标识
        comment.setCommentType(ConstantUtil.MOVEMENT_LIKE_1);
        //设置点赞动态id
        comment.setPublishId(new ObjectId(movementId));
        //设置操作人id
        comment.setUserId(userId);
        //向redis中添加一个标志,标识xx用户对xx动态做了点赞
        String key = StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movementId);
        stringRedisTemplate.opsForValue().set(key, "1");
        //调用方法,发送mq消息
        movementMQManager.sendMsg(movementId, MovementMQManager.MOVEMENT_LIKE);
        return commentService.saveComment(comment);
    }

    /**
     * 删除点赞动态
     *
     * @param movementId 动态id
     * @return 点赞数
     */
    @Logger(type = "0206")
    public Integer disLikeMovement(String movementId) {
        //获取当前登录对象
        Long userId = UserHolder.getId();
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setUserId(userId);
        comment.setPublishId(new ObjectId(movementId));
        comment.setCommentType(ConstantUtil.MOVEMENT_LIKE_1);
        //将点赞标识从redis中删除
        String key = StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movementId);
        stringRedisTemplate.delete(key);
        //调用方法,发送mq消息
        movementMQManager.sendMsg(movementId, MovementMQManager.MOVEMENT_DISLIKE);
        //删除点赞
        return commentService.deleteComment(comment);
    }

    /**
     * 喜欢动态
     *
     * @param movementId 动态id
     * @return 喜欢数
     */
    @Logger(type = "0204")
    public Integer loveMovement(String movementId) {
        //获取当前登录对象
        Long userId = UserHolder.getId();
        //构建评论对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(new ObjectId(movementId));
        comment.setUserId(userId);
        comment.setCommentType(ConstantUtil.MOVEMENT_LOVE_3);
        //向redis中存储喜爱标识
        String key = StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, movementId);
        stringRedisTemplate.opsForValue().set(key, "1");
        //调用方法,发送mq消息
        movementMQManager.sendMsg(movementId, MovementMQManager.MOVEMENT_LOVE);
        return commentService.saveComment(comment);
    }

    /**
     * 取消喜欢动态
     *
     * @param movementId 动态id
     * @return 喜欢数
     */
    @Logger(type = "0207")
    public Integer unLoveMovement(String movementId) {
        Long useId = UserHolder.getId();
        Comment comment = new Comment();
        comment.setUserId(useId);
        comment.setPublishId(new ObjectId(movementId));
        comment.setCreated(System.currentTimeMillis());
        comment.setCommentType(ConstantUtil.MOVEMENT_LOVE_3);
        //
        String key = StrUtil.format(ConstantUtil.MOVEMENT_LOVE, useId, movementId);
        stringRedisTemplate.delete(key);
        //调用方法,发送mq消息
        movementMQManager.sendMsg(movementId, MovementMQManager.MOVEMENT_DISLOVE);
        return commentService.deleteComment(comment);
    }

    /**
     * 查询单条动态信息
     *
     * @param movementId 动态id
     * @return 动态vo对象
     */
    public MovementVo findMovement(String movementId) {
        //根据动态id查询动态
        Movement movement = movementService.findMovement(movementId);
        //查询动态的发布人

        UserInfo userInfo = userInfoService.findById(movement.getUserId());
        MovementVo movementVo = new MovementVo();
        movementVo.setUserInfo(userInfo);
        movementVo.setMovement(movement);
        //保存访问记录
        visitorService.saveVisitor(UserHolder.getId(), movement.getUserId(), ConstantUtil.VISITOR_SOURCE_INDEX);
        //调用方法,发送mq消息
        movementMQManager.sendMsg(movementId, MovementMQManager.MOVEMENT_BROWSE);
        return movementVo;
    }

    /**
     * 查询评论列表
     *
     * @param movementId 动态id
     * @param page       页码
     * @param pageSize   每页条数
     * @return 页面显示对象
     */
    public PageBeanVo findCommentList(String movementId, Integer page, Integer pageSize) {
        //根据movementId查询评论列表
        PageBeanVo pageBeanVo = commentService.findCommentList(page, pageSize, movementId);
        List<Comment> items = (List<Comment>) pageBeanVo.getItems();
        List<CommentVo> commentVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(items)) {
            for (Comment comment : items) {
                CommentVo commentVo = new CommentVo();
                //查询发布该条评论的人的个人信息
                UserInfo userInfo = userInfoService.findById(comment.getUserId());
                BeanUtil.copyProperties(userInfo, commentVo);
                BeanUtil.copyProperties(comment, commentVo);
                commentVo.setCreateDate(DateFormatUtil.format(new Date(comment.getCreated())));
                String key = StrUtil.format(ConstantUtil.COMMENT_LIKE, UserHolder.getId(), comment.getId());
                if (stringRedisTemplate.hasKey(key)) {
                    commentVo.setHasLiked(1);
                }
                commentVoList.add(commentVo);
            }
        }
        System.out.println("动态列表" + items);
        pageBeanVo.setItems(commentVoList);
        return pageBeanVo;
    }

    @Reference
    private VisitorService visitorService;

    /**
     * 发布评论
     *
     * @param movementId  动态id
     * @param commentText 评论内容
     */
    @Logger(type = "0205")
    public void saveComment(String movementId, String commentText) {
        Long id = UserHolder.getId ();
        String phone = userService.userIdByPhone (id);
        Jedis jedis = new Jedis("192.168.136.160", 6379);
        jedis.select (1);
        String s = jedis.get (ConstantUtil.FREEZE_USERComment + phone);
        if (s != null) {
            throw new RuntimeException ("该用户评论已经被封禁");
        }
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(movementId));
        comment.setUserId(UserHolder.getId());
        comment.setCreated(System.currentTimeMillis());
        comment.setContent(commentText);
        comment.setCommentType(ConstantUtil.MOVEMENT_COMMENT_2);
        commentService.saveComment(comment);
        //调用方法,发送mq消息
        movementMQManager.sendMsg(movementId, MovementMQManager.MOVEMENT_COMMENT);
    }

    /**
     * 查询点赞列表
     *
     * @param page        页码
     * @param pageSize    每页条数
     * @param commentType 操作类型
     * @return 数据封装
     */
    public PageBeanVo message(Integer page, Integer pageSize, Integer commentType) {
        Long userId = UserHolder.getId();
        //查询点赞列表
        PageBeanVo pageBeanVo = movementService.findMovementByCommentType(page, pageSize, commentType, userId);
        List<Comment> items = (List<Comment>) pageBeanVo.getItems();
        List<UserCommentVo> voList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(items)) {
            for (Comment item : items) {
                UserCommentVo vo = new UserCommentVo();
                UserInfo userInfo = userInfoService.findById(item.getUserId());
                BeanUtil.copyProperties(userInfo, vo);
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                String date = format.format(item.getCreated());
                vo.setCreateDate(date);
                voList.add(vo);
            }
        }
        pageBeanVo.setItems(voList);
        return pageBeanVo;
    }



    /**
     * 动态评论点赞
     * @param publishId
     * @return
     */
    public Integer likeMovementComment(String publishId) {
        //获得当前登录人id
        Long loginUserId = UserHolder.getId();
        Comment comment = new Comment();
        comment.setUserId(loginUserId);
        comment.setPublishId(new ObjectId(publishId));

        Integer count = commentService.saveLikeMovementComment(comment);
        //设置工具类保存解析
        String key = StrUtil.format(ConstantUtil.MOVEMENT_COMMENT_LIKE, loginUserId, publishId);
        System.err.println(key);
        //向redis中保存点赞标识
        stringRedisTemplate.opsForValue().set(key , "动态评论点赞");


        return count;
    }


    /**
     * 动态评论取消点赞
     * @param publishId
     * @return
     */
    public Integer disLikeMovementComment(String publishId) {

        Long loginUserId = UserHolder.getId();

        String key = StrUtil.format(ConstantUtil.MOVEMENT_COMMENT_LIKE, loginUserId, publishId);

        //直接删除redis中保存的点赞标识
        stringRedisTemplate.delete(key);
        //调方法删除
        return commentService.disLikeMovementComment(publishId);

    }
}
